package cn.dakaqi.utils.latitude;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.lang3.StringUtils;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;

public class LatitudeUtils
{

    public static final String AK = "dALwUrFHP74TuZBdQTVjNGD3";
    private static final double EARTH_RADIUS = 6378137;
    private static final double PI = 3.14159265;
    private static final double RAD = Math.PI / 180.0;

    /**
     * 返回输入地址的经纬度坐标
     * key lng(经度),lat(纬度)
     */
    public static Map<String, String> getGeocoderLatitude(String address)
    {
        System.out.println("getGeocoderLatitude--------->" + address);
        BufferedReader in = null;
        try
        {
            if (StringUtils.isEmpty(address))
                return null;

            //将地址转换成utf-8的16进制
            address = URLEncoder.encode(address, "UTF-8");
//       如果有代理，要设置代理，没代理可注释
//		System.setProperty("http.proxyHost","192.168.1.188");
//		System.setProperty("http.proxyPort","3128");
            URL tirc = new URL("http://api.map.baidu.com/geocoder?address=" + address + "&output=json&ak=" + AK);

            in = new BufferedReader(new InputStreamReader(tirc.openStream(), "UTF-8"));
            String res;
            StringBuilder sb = new StringBuilder("");
            while ((res = in.readLine()) != null)
            {
                sb.append(res.trim());
            }
            String str = sb.toString();
            Map<String, String> map = null;
            if (StringUtils.isNotEmpty(str))
            {
                int lngStart = str.indexOf("lng\":");
                int lngEnd = str.indexOf(",\"lat");
                int latEnd = str.indexOf("},\"precise");
                if (lngStart > 0 && lngEnd > 0 && latEnd > 0)
                {
                    String lng = str.substring(lngStart + 5, lngEnd);
                    String lat = str.substring(lngEnd + 7, latEnd);
                    map = new HashMap<String, String>();
                    map.put("lng", lng);
                    map.put("lat", lat);
                    return map;
                }
            }
        } catch (Exception e)
        {
            e.printStackTrace();
        } finally
        {
            try
            {
                if (null != in)
                    in.close();
            } catch (IOException e)
            {
                e.printStackTrace();
            }
        }
        return null;
    }

    private static double rad(double d)
    {
        return d * RAD;
    }

    /**
     * 根据两点间经纬度坐标（double值），计算两点间距离，单位为米
     *
     * @param lng1
     * @param lat1
     * @param lng2
     * @param lat2
     * @return
     */
    public static double GetDistance(double lng1, double lat1, double lng2, double lat2)
    {
        double radLat1 = rad(lat1);
        double radLat2 = rad(lat2);
        double a = radLat1 - radLat2;
        double b = rad(lng1) - rad(lng2);
        double s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2) +
                Math.cos(radLat1) * Math.cos(radLat2) * Math.pow(Math.sin(b / 2), 2)));
        s = s * EARTH_RADIUS;
        s = Math.round(s * 10000) / 10000;
        return s;
    }

    /**
     * 根据提供的经度和纬度、以及半径，取得此半径内的最大最小经纬度
     *
     * @param raidus 单位米
     *               return minLat,minLng,maxLat,maxLng
     */
    public static double[] getAround(double lat, double lon, int raidus)
    {

        Double latitude = lat;
        Double longitude = lon;

        Double degree = (24901 * 1609) / 360.0;
        double raidusMile = raidus;

        Double dpmLat = 1 / degree;
        Double radiusLat = dpmLat * raidusMile;
        Double minLat = latitude - radiusLat;
        Double maxLat = latitude + radiusLat;

        Double mpdLng = degree * Math.cos(latitude * (PI / 180));
        Double dpmLng = 1 / mpdLng;
        Double radiusLng = dpmLng * raidusMile;
        Double minLng = longitude - radiusLng;
        Double maxLng = longitude + radiusLng;
        System.out.println("[" + minLat + "," + minLng + "," + maxLat + "," + maxLng + "]");
        return new double[]{minLat, minLng, maxLat, maxLng};
    }

    public static Map<String, String> getGeocoderAddress(double lat, double lng)
    {
        Map<String, String> map = null;
        BufferedReader in = null;
        try
        {
            String url = "http://api.map.baidu.com/geocoder/v2/?ak=" + AK + "&location=" + lat + "," + lng + "&output=json&pois=1";
            System.out.println("LatitudeUtils-------->" + url);
            URL tirc = new URL(url);

            in = new BufferedReader(new InputStreamReader(tirc.openStream(), "UTF-8"));
            String res;
            StringBuilder sb = new StringBuilder("");
            while ((res = in.readLine()) != null)
            {
                sb.append(res.trim());
            }
            String str = sb.toString();

            if (StringUtils.isNotEmpty(str))
            {
                map = new HashMap<String, String>();
                JSONObject jsonObject = JSON.parseObject(str);
                JSONObject result = jsonObject.getJSONObject("result");
                String address = result.getString("formatted_address");
                JSONObject addressComponent = result.getJSONObject("addressComponent");
                String city = addressComponent.getString("city");
                String country = addressComponent.getString("country");
                String direction = addressComponent.getString("direction");
                String distance = addressComponent.getString("distance");
                String district = addressComponent.getString("district");
                String province = addressComponent.getString("province");
                String street = addressComponent.getString("street");
                map.put("address", address);
                map.put("province", province);
                map.put("city", city);
                map.put("district", district);
                map.put("street", street);
                System.out.println("[" + lat + "," + lng + "]---->" + province + "," + city + "," + district + "," + street + "," + address);
            }

        } catch (Exception e)
        {
            e.printStackTrace();
        } finally
        {
            try
            {
                if (null != in)
                    in.close();
            } catch (IOException e)
            {
                e.printStackTrace();
            }
        }
        return map;
    }

    //http://api.map.baidu.com/geocoder/v2/?ak=dALwUrFHP74TuZBdQTVjNGD3&location=31.258338,121.387541&output=json&pois=1
    public static void main(String args[])
    {
//        Map<String, String> json = LatitudeUtils.getGeocoderLatitude("104台湾台北市中山區中山北路二段45巷1号–2号");
//        System.out.println("lng : " + json.get("lng"));
//        System.out.println("lat : " + json.get("lat"));
//        json = LatitudeUtils.getGeocoderLatitude("104台湾台北市中山區中山北路二段45巷1号–2号");
//        System.out.println("lng : " + json.get("lng"));
//        System.out.println("lat : " + json.get("lat"));
//        double distance = GetDistance(120.8876, 31.96266, 120.894171, 32.012176);
//        System.out.println("Distance is:" + distance);


        getGeocoderAddress(23.61996, 104.09771);
        //getGeocoderAddress(39.947107,116.282446);
//        lng : 121.36565
//        lat : 31.227378
//        lng : 121.387541
//        lat : 31.258338

    }

}

